#!/usr/bin/perl
# IBM_PROLOG_BEGIN_TAG 
# This is an automatically generated prolog. 
#  
#  
#  
# Licensed Materials - Property of IBM 
#  
# Restricted Materials of IBM 
#  
# (C) COPYRIGHT International Business Machines Corp. 2003,2004 
# All Rights Reserved 
#  
# US Government Users Restricted Rights - Use, duplication or 
# disclosure restricted by GSA ADP Schedule Contract with IBM Corp. 
#  
# IBM_PROLOG_END_TAG 
####################################################################
#
#   verifylink command
#
#   Syntax:  verifylink {-f <frame> -g <cage> 
#                        [{-c <chip>|-a <adapter>} [-o <port>]] 
#                        | --help }
#
#            -f <frame>      - Specifies the frame for the link(s) to be
#				tested
#            -g <cage>       - Specifies the cage for the link(s) to be
#				tested
#            -c <chip>       - Specifies the chip for the link(s) to be
#                               tested
#            -a <adapter>    - Specifies the adapter for the link(s) to be
#                               tested
#            -o <port>       - Specifies the port for the link(s) to be
#                               tested
#            --help          - Prints this message
#
####################################################################
#
#   Initial version - 12/11/02
#
####################################################################

use Getopt::Long;

#
# Include the following Perl script here to help process the i_stub_FS 
# return codes.
#
require "/opt/hsc/bin/i_stub_msg.pl" ;

sub bynumber { $a <=> $b; }

sub exit_routine {
    
	# Print out results array if there were any errors

	if ($BAD_RESULTS == 1) {
		if ($NUM_BAD_RESULTS == 1) {
			print "\nThe following test was unsuccessful:\n";
		} else {
			print "\nThe following tests were unsuccessful:\n";
		}
		
		print "\n";
		for ($m = 0; $m < $NUM_BAD_RESULTS; $m++) {
			$i_stub_return = $BAD_RESULTS_i_stub_return[$m];
			&i_stub_msg;
			print "\tFrame = ", $frame_parm, " Cage = ", $cage_parm, " Device = ", $BAD_RESULTS_DEVICE[$m], " Port = ", $BAD_RESULTS_PORT[$m], ": ", $RC_MSG;
		}
		$ret = 1;
	} else {
		if ($TEST_RUN == 1) {
			print "\nAll devices tested successfully.\n";
		}
		$ret = 0;
	}

	exit $ret; 

} # end exit_routine subroutine

################################################################################
#
# start main body of code
#
################################################################################
$PRGRM  = "verifylink";
$BIN    = "/opt/hsc/bin"; 
$I_STUB_FS = "/opt/hsc/bin/i_stub_FS";

$MAX_CHIPS = 8;
$MAX_ADAP = 8;
$MAX_CHIP_PORTS = 8;
$MAX_ADAP_PORTS = 2;
$BAD_LOC_ID = 51;

$SWITCH = 1;

$TEST_RUN = 0;

$BAD_RESULTS = 0;
$NUM_BAD_RESULTS = 0;

$USAGE = "Usage:  verifylink {-f <frame> -g <cage> [{-c <chip>|-a <adapter>} [-o <port>]] | --help }\n";

# First check for existence of parameters
if ($#ARGV == -1) {
#	print "No parms\n";     #DEBUG
	print $USAGE;
	$ret = 1;
	&exit_routine;
}

# Get parameters used

Getopt::Long::Configure("no_ignore_case");
$result = GetOptions(
        "help" => \$help,
        "f=s" => \$frame,
        "g=s" => \$cage,
        "c=s" => \$chip,
        "a=s" => \$adapter,
        "o=s" => \$port,
);

#print "GetOptions rc is ", $result, " .\n";

if ($result == 0) {
	# Bad result from GetOptions
#	print "Bad result from GetOptions\n";     #DEBUG
	print $USAGE;      #USAGE
	$ret = 1;
	&exit_routine;
}

if ($help) {
	# help was asked for
#	print "help was specified\n";     #DEBUG
	print $USAGE;      #USAGE
	$ret = 0;
	&exit_routine;
}

if (defined $frame) {
	$frame_parm = $frame;
	if ($frame_parm =~ /\D/) {
#		print "Bad -f value - not a number\n";     #DEBUG
		print $USAGE;
		$ret = 1;
		&exit_routine;
	}
}
else {
	# No -f or nothing else was specified after -f
#	print "No -f value\n";     #DEBUG
	print $USAGE;
	$ret = 1;
	&exit_routine;
}

if (defined $cage) {
	$cage_parm = $cage;
	if ($cage_parm =~ /\D/) {
#		print "Bad -g value - not a number\n";     #DEBUG
		print $USAGE;
		$ret = 1;
		&exit_routine;
	}
	else {
		#CHECK ON MAX CAGE VALUE?
	}
}
else {
	# No -g or nothing else was specified after -g
#	print "No -g value\n";     #DEBUG
	print $USAGE;
	$ret = 1;
	&exit_routine;
}

if (defined $chip) {
	$chip_parm = $chip;
	if ($chip_parm =~ /\D/) {
#		print "Bad -c value - not a number\n";     #DEBUG
		print $USAGE;
		$ret = 1;
		exit $ret;
	}
	if (($chip_parm < 0) || ($chip_parm > 7)) {
#		print "Bad -c value - not 0-7\n";     #DEBUG
		print $USAGE;
		$ret = 1;
		exit $ret;
	}
	$h_parm = $chip;
}

if (defined $adapter) {
	$adap_parm = $adapter;
	if ($adap_parm =~ /\D/) {
#		print "Bad -a value - not a number\n";     #DEBUG
		print $USAGE;
		$ret = 1;
		exit $ret;
	}
	if (($adap_parm < 0) || ($adap_parm > 7)) {
#		print "Bad -a value - not 0-7\n";     #DEBUG
		print $USAGE;
		$ret = 1;
		exit $ret;
	}
	$h_parm = $adapter;
}

if (defined $port) {
	$port_parm = $port;
	if ($port_parm =~ /\D/) {
#		print "Bad -o value - not a number\n";     #DEBUG
		print $USAGE;
		$ret = 1;
		exit $ret;
	}
	if (defined $chip) {
		if (($port_parm < 0) || ($port_parm > 7)) {
#			print "Bad -o value - not 0-7\n";     #DEBUG
			print $USAGE;
			$ret = 1;
			exit $ret;
		}
	} else {
		if (($port_parm < 0) || ($port_parm > 1)) {
#			print "Bad -p value - not 0-1\n";     #DEBUG
			print $USAGE;
			$ret = 1;
			exit $ret;
		}
	}
}

# Make sure no invalid combos were passed
if ((defined $chip) && (defined $adapter)) {
#	print "Cannot specify -c and -a together\n";    #DEBUG
	print $USAGE;
	$ret = 1;
	exit $ret;
}

if ((defined $port) && ((!defined $chip) && (!defined $adapter))) {
#	print "If -o, then must have either -a or -c\n";  #DEBUG
	print $USAGE;
	$ret = 1;
	exit $ret;
}

# Now that we've determined that the user specified all the required parms
#      and passed reasonable values with them, see how many times we have
#      to issue the i_stub_FS command
if (defined $port) {
	# -p was specified, so we're only testing one link
	print "Issuing Verify Link Diagnostic Test to Frame = ", $frame_parm, " Cage = ", $cage_parm, " Device = ", $h_parm, " Port = ", $port_parm, "\n";
	$i_stub_return = `$I_STUB_FS diag -t 0 -f $frame_parm -c $cage_parm -h $h_parm -p $port_parm`;
#	print "$I_STUB_FS diag -t 0 -f $frame_parm -c $cage_parm -h $h_parm -p $port_parm\n";

	$TEST_RUN = 1;
	# Check return code from i_stub_FS
	if ($i_stub_return != 0) {
		$BAD_RESULTS = 1;
		$BAD_RESULTS_i_stub_return[$NUM_BAD_RESULTS] = $i_stub_return;
		$BAD_RESULTS_DEVICE[$NUM_BAD_RESULTS] = $h_parm;
		$BAD_RESULTS_PORT[$NUM_BAD_RESULTS] = $port_parm;
		$NUM_BAD_RESULTS += 1;
	}
	else {
		$ret = 0;
	}
}
elsif (defined $chip) {
	# No -o but there was a -c so we want to test multiple ports
	#   of the same chip
	for ($i = 0; $i < $MAX_CHIP_PORTS; $i++) {
		print "Issuing Verify Link Diagnostic Test to Frame = ", $frame_parm, " Cage = ", $cage_parm, " Device = ", $h_parm, " Port = ", $i, "\n";
		$i_stub_return = `$I_STUB_FS diag -t 0 -f $frame_parm -c $cage_parm -h $h_parm -p $i`;

		$TEST_RUN = 1;
		# Check return code from i_stub_FS
		if ($i_stub_return != 0) {
			$BAD_RESULTS = 1;
			$BAD_RESULTS_i_stub_return[$NUM_BAD_RESULTS] = $i_stub_return;
			$BAD_RESULTS_DEVICE[$NUM_BAD_RESULTS] = $h_parm;
			$BAD_RESULTS_PORT[$NUM_BAD_RESULTS] = $i;
			$NUM_BAD_RESULTS += 1;
		}
	}
}
elsif (defined $adapter) {
	# No -o but there was a -a so we want to test multiple ports
	#   of the same adapter
	for ($i = 0; $i < $MAX_ADAP_PORTS; $i++) {
		print "Issuing Verify Link Diagnostic Test to Frame = ", $frame_parm, " Cage = ", $cage_parm, " Device = ", $h_parm, " Port = ", $i, "\n";
		$i_stub_return = `$I_STUB_FS diag -t 0 -f $frame_parm -c $cage_parm -h $h_parm -p $i`;

		$TEST_RUN = 1;
		# Check return code from i_stub_FS
		if ($i_stub_return != 0) {
			$BAD_RESULTS = 1;
			$BAD_RESULTS_i_stub_return[$NUM_BAD_RESULTS] = $i_stub_return;
			$BAD_RESULTS_DEVICE[$NUM_BAD_RESULTS] = $h_parm;
			$BAD_RESULTS_PORT[$NUM_BAD_RESULTS] = $i;
			$NUM_BAD_RESULTS += 1;
		}
	}
}
else {
	# Only -f and -g were specified, so we want to test all the ports
        #   of a switch or in a server.  Assume switch first.
	OUTER: for ($i = 0; $i < $MAX_CHIPS; $i++) {
		INNER: for ($j = 0; $j < $MAX_CHIP_PORTS; $j++) {
			$TEST_RUN = 1;
			$i_stub_return = `$I_STUB_FS diag -t 0 -f $frame_parm -c $cage_parm -h $i -p $j`;

	 		# Check return code from i_stub_FS
			if ($i_stub_return != 0) {
				$BAD_RESULTS = 1;
				$BAD_RESULTS_i_stub_return[$NUM_BAD_RESULTS] = $i_stub_return;
				$BAD_RESULTS_DEVICE[$NUM_BAD_RESULTS] = $i;
				$BAD_RESULTS_PORT[$NUM_BAD_RESULTS] = $j;
				$NUM_BAD_RESULTS += 1;
				if (($i_stub_return == $BAD_LOC_ID) && ($j == 2)) {
					$SWITCH = 0;
					$NUM_BAD_RESULTS -= 1;
					last OUTER;
				}
				else {
					print "Issuing Verify Link Diagnostic Test to Frame = ", $frame_parm, " Cage = ", $cage_parm, " Device = ", $i, " Port = ", $j, "\n";
				}
			}
		       else {
			       print "\tIssuing Line Continuity Diagnostic Test to Frame = ", $frame_parm, " Cage = ", $cage_parm, " Device = ", $i, " Port = ", $j, "\n";
		       }
		}
	}
}

# See if we bailed out because we got an invalid location id return code.  If so, we need
#   to continue with the adapter testing
if ($SWITCH == 0) {
	for ($k = 1; $k < $MAX_ADAP; $k++) {
		for ($l = 0; $l < $MAX_ADAP_PORTS; $l++) {
			print "Issuing Verify Link Diagnostic Test to Frame = ", $frame_parm, " Cage = ", $cage_parm, " Device = ", $k, " Port = ", $l, "\n";
			$i_stub_return = `$I_STUB_FS diag -t 0 -f $frame_parm -c $cage_parm -h $k -p $l`;

			$TEST_RUN = 1;
			# Check return code from i_stub_FS
			if ($i_stub_return != 0) {
				$BAD_RESULTS = 1;
				$BAD_RESULTS_i_stub_return[$NUM_BAD_RESULTS] = $i_stub_return;
				$BAD_RESULTS_DEVICE[$NUM_BAD_RESULTS] = $k;
				$BAD_RESULTS_PORT[$NUM_BAD_RESULTS] = $l;
				$NUM_BAD_RESULTS += 1;
			}
                }
        }
}

# Print out results array if there were any errors

&exit_routine;

